package com.wheel.autoconfigure.drools;

import com.wheel.core.utils.Log;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class DroolsBeanRegister {

    private static final Logger log = LoggerFactory.getLogger(DroolsBeanRegister.class);

    public DroolsBeanRegister(DroolsAutoConfigurationProperties properties, DefaultListableBeanFactory factory) throws IOException {
        System.setProperty("drools.dateformat", properties.getDateFormat());
        Log.info(log, "set drools.dateformat:{}", properties.getDateFormat());
        registerContainersBean(properties, factory);
        Log.registered(log);
    }

    public void registerContainersBean(DroolsAutoConfigurationProperties properties, DefaultListableBeanFactory beanFactory) throws IOException {
        Log.registered(log);
        Map<String, KieContainerProperties> containers = properties.getContainers();
        if(containers==null){
            Log.info(log, "没找到w.drools.container的配置");
            return;
        }
        boolean onlyUseDefault = containers.size() == 1;
        for (String key : containers.keySet()) {
            registerBean(key, containers.get(key), beanFactory, onlyUseDefault);
        }
    }

    private void registerBean(String beanName, KieContainerProperties kcp, DefaultListableBeanFactory beanFactory, boolean onlyUseDefault) throws IOException {
        AbstractBeanDefinition beanDefinition = getBeanDefinition(beanName, kcp.getLocationPatterns(), kcp.getScannerInterval(), onlyUseDefault);
        beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
        beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }


    private static final String ATTRIBUTE_CONTAINER = "container";
    /**
     * <dt>Description:getBeanDefinition</dt>
     * <dd></dd>
     * <dd>author: wnfbx</dd>
     * <dd>version:1.0 <i>2021/8/9 16:38</i></dd>
     *
     * @return org.springframework.beans.factory.support.AbstractBeanDefinition
     * see org.kie.spring.factorybeans.KieImportFactoryBean
     * see org.kie.spring.namespace.KieImportDefinitionParser#parseInternal(Element, ParserContext)
     * @since jdk1.7+
     */
    AbstractBeanDefinition getBeanDefinition(String beanName, List<String> locationPatterns, int scanningInterval, boolean onlyUseDefault) throws IOException {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(KieContainerFactoryBean.class);
        KieServices kieServices = DroolsUtils.getKieServices();
        KieContainer kieContainer = DroolsUtils.newKieContainer(kieServices, DroolsUtils.newKieModule(kieServices, DroolsUtils.kieFileSystem(kieServices, locationPatterns)));
        if (!onlyUseDefault && !KieSessionTemplate.DEFAULT_CONTAINER_KEY.equals(beanName)) {
            DroolsUtils.validateConfig(kieContainer.getKieBase());
        }
        DroolsUtils.createKieScannerAndStart(kieServices, kieContainer, scanningInterval);
        builder.addPropertyValue(ATTRIBUTE_CONTAINER, kieContainer);
        return builder.getBeanDefinition();
    }
}